
package com.kanjian.music.xmpp;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;

import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.SASLAuthentication;
import org.jivesoftware.smack.SmackAndroid;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smackx.muc.Affiliate;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.muc.SubjectUpdatedListener;
import org.jivesoftware.smackx.ping.PingManager;

import com.kanjian.music.KanjianApplication;

import android.os.Build;

/**
 * 在线聊天方法
 * 
 * @author xuyanjun
 */
public class XMPPManager {

    private static XMPPManager mInstance;

    private XMPPManager() {
    }

    public static XMPPManager getIntance() {
        if (mInstance == null) {
            mInstance = new XMPPManager();
        }
        return mInstance;
    }

    static {
        try {
            Class.forName("org.jivesoftware.smack.ReconnectionManager");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private XMPPConnection connection;

    private ArrayList<OnChatListener> mListenerList = new ArrayList<OnChatListener>();

    public boolean conServer() {
        SmackAndroid.init(KanjianApplication.getContext());
        ConnectionConfiguration config = new ConnectionConfiguration("test-xmpp.kanjian.com");
        // ConnectionConfiguration config = new
        // ConnectionConfiguration("talk.kanjian.com", 8040);
        config.setSASLAuthenticationEnabled(true);
        config.setCompressionEnabled(true);
        config.setSecurityMode(SecurityMode.enabled);
        config.setReconnectionAllowed(true);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            config.setTruststoreType("AndroidCAStore");
            config.setTruststorePassword(null);
            config.setTruststorePath(null);
        } else {
            config.setTruststoreType("BKS");
            String path = System.getProperty("javax.net.ssl.trustStore");
            if (path == null)
                path = System.getProperty("java.home") + File.separator + "etc" + File.separator
                        + "security" + File.separator + "cacerts.bks";
            config.setTruststorePath(path);
        }

        connection = new XMPPConnection(config);
        PingManager manager = PingManager.getInstanceFor(connection);
        System.out.println(manager.ping(""));
        try {
            connection.connect();
            return true;
        } catch (XMPPException e) {
            e.printStackTrace();
        }
        return false;
    }

    public boolean login(String uName, String pwd) {
        if (conServer()) {
            try {
                SASLAuthentication.supportSASLMechanism("PLAIN", 0);
                connection.login(uName, pwd);
                return true;
            } catch (XMPPException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    public MultiUserChat joinRoom(String roomId, String user, String pwd) {
        final MultiUserChat muc = new MultiUserChat(connection, roomId);
        try {
            muc.join(user, pwd);
            muc.addMessageListener(new PacketListener() {
                @Override
                public void processPacket(Packet packet) {
                    if (packet instanceof Message) {
                        Message msg = (Message) packet;
                        notifyMessage(msg);
                    }
                }
            });
            // 监听聊天室用户变化， 暂时无效
            muc.addParticipantListener(new PacketListener() {
                @Override
                public void processPacket(Packet arg0) {
                    // System.out.println(arg0);
                    try {
                        System.out.println(muc.getAdmins());
                        System.out.println(muc.getMembers());
                        Collection<Affiliate> list = muc.getMembers();
                        for (Affiliate a : list) {
                            Message msg = new Message();
                            msg.setBody(a.getNick() + "!! 加入房间!");
                            notifyMessage(msg);
                        }
                    } catch (XMPPException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            });

        } catch (XMPPException e) {
            e.printStackTrace();
        }
        return muc;
    }

    public void logout() {
        if (connection.isConnected()) {
            connection.disconnect();
        }
    }

    public ChatManager getChatManager() {
        if (connection != null) {
            return connection.getChatManager();
        } else {
            return null;
        }
    }

    public XMPPConnection getConnection() {
        if (connection != null) {
            return connection;
        } else {
            return null;
        }
    }

    public void registerOnChatListener(OnChatListener listener) {
        mListenerList.add(listener);
    }

    public void unregisterOnChatListener(OnChatListener listener) {
        mListenerList.remove(listener);
    }

    private void notifyMessage(Message msg) {
        int size = mListenerList.size();
        for (int i = 0; i < size; i++) {
            mListenerList.get(i).onMessage(msg);
        }
    }

}
